﻿using System;
using System.Net;
using HtmlAgilityPack;
using iReaper.IndexService.Common;
using iReaper.IndexService.Common.TaskEngine;
using iReaper.IndexService.Common.WebTools;

namespace iReaper.IndexService.MSEvents
{
    public class RawIndexParseTTask : TaskBase
    {
        int m_iCountInWeek;
        string m_userName;
        string m_password;

        #region ITask Members

        public override void Start()
        {
            if (System.IO.File.Exists(".\\Credential.txt"))
            {
                System.IO.StreamReader reader = new System.IO.StreamReader(".\\Credential.txt");
                m_userName = reader.ReadLine();
                m_password = reader.ReadLine();
                reader.Close();
            }

            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread t = new System.Threading.Thread(ProcessEventItem);
                t.Start();
            }
        }

        private void ProcessEventItem()
        {
            using (MSAwareWebClient client = new MSAwareWebClient(m_userName, m_password))
            {
                EventItem item = null;
                bool retry = false;
                int retryCount = 0;
                while (true)
                {
                    if (!retry)
                    {
                        item = GetItem();
                        if (item == null)
                        {
                            Done();
                            return;
                        }
                    }
                    //System.Threading.Thread.Sleep(100);
                    try
                    {
                        string regURL = string.Format("https://msevents.microsoft.com/cui/Register.aspx?EventID={0}&culture={1}&countryCode=US&IsRedirect=false", item.EventID, item.Language);
                        // 
                        // Confirm
                        string content = client.DownloadString(regURL);
                        HtmlAgilityPack.HtmlDocument htmldoc = new HtmlDocument();
                        htmldoc.LoadHtml(content);
                        if (htmldoc.DocumentNode.SelectSingleNode("//input[@type='submit' and @value='Confirm']") != null)
                        {
                            FormParser parser = new FormParser(content);
                            var form = parser.Forms[0];
                            form.ActionUrl = regURL;// new Uri(new Uri(item.DownloadUrl), form.ActionUrl).ToString();
                            var content2 = form.Submit(client, "Confirm");

                            // 
                            htmldoc = new HtmlDocument();
                            htmldoc.LoadHtml(content2);
                        }
                        var nodeView = htmldoc.DocumentNode.SelectSingleNode("//a[text()='View Online' or text()='ViewOnline']");
                        if (nodeView != null)
                        {
                            string url = nodeView.Attributes["href"].Value;
                            var nodeRegId = htmldoc.DocumentNode.SelectSingleNode("//input[@type='hidden' and @id='hdnRegID']");
                            item.RegistrationId = nodeRegId.Attributes["value"].Value;

                            item.DownloadUrl = ParseRAWLMUrl(url, item.RegistrationId, item.Language, "");
                        }
                        int complet = System.Threading.Interlocked.Decrement(ref m_iCountInWeek);
                        RaiseProgress(complet);
                        retryCount = 0;
                        retry = false;
                        SetResult(item);
                    }
                    catch (System.Net.WebException)
                    {
                        retryCount++;
                        if (retryCount < 3)
                        {
                            retry = true;
                        }
                        else
                        {
                            retry = false;
                            System.Threading.Interlocked.Decrement(ref m_iCountInWeek);
                        }
                    }
                    catch (System.Exception ex)
                    {
                        retry = false;
                        // give up
                        System.Threading.Interlocked.Decrement(ref m_iCountInWeek);
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(ex.StackTrace);
                    } // skip any error, continue next.
                }
            }

        }

        private string ParseRAWLMUrl(string LMStr, string RegistrationID, string culture, string parent)
        {
            if (string.IsNullOrEmpty(LMStr))
            {
                return string.Empty;
            }

            Uri uri;
            if (!Uri.TryCreate(LMStr, UriKind.Absolute, out uri))
            {
                return string.Empty;
            }

            switch (uri.Scheme)
            {
                case "http":
                case "https":
                    var queries = System.Web.HttpUtility.ParseQueryString(uri.Query);
                    string idValue = null, pwValue = null;
                    foreach (string key in queries.Keys)
                    {
                        if (key.ToLower() == "id")
                        {
                            idValue = queries[key];
                        }
                        else if (key.ToLower() == "pw")
                        {
                            pwValue = queries[key];
                        }
                    }
                    // Check if both id and pw is presented
                    if (idValue != null && pwValue != null)
                    {
                        return string.Format("{0}://{1}{2}?id={3}&pw={4}&fmt=dll",
                                              uri.Scheme,
                                              uri.Host,
                                              uri.AbsolutePath,
                                              idValue,
                                              pwValue);
                    }
                    else
                    {
                        return "";
                    }
                case "javascript":
                    string path = uri.AbsolutePath;
                    if (parent == uri.Scheme)
                    {
                        return "";
                    }

                    if (path.StartsWith("CheckFormat("))
                    {
                        int start = "CheckFormat(".Length;
                        int end = path.Length - 2;

                        if (end > start)
                        {
                            string parameters = path.Substring(start, end - start + 1);
                            string[] values = parameters.Split(',');
                            for (int i = 1; i < values.Length; i++)
                            {
                                if (values[i] == "true")
                                {
                                    // Build JoinMeeting uri
                                    string url = string.Format("https://msevents.microsoft.com/cui/joinmeeting.aspx?RegistrationID={0}&RecordingFmt={1}&Culture={2}",
                                                               RegistrationID,
                                                               i,
                                                               culture);
                                    // Get actual livemeeting url
                                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                                    request.AllowAutoRedirect = false;
                                    request.Method = "HEAD";
                                    var response = request.GetResponse();
                                    string responseUrl = response.Headers[HttpResponseHeader.Location];
                                    response.Close();

                                    return ParseRAWLMUrl(responseUrl, RegistrationID, culture, uri.Scheme);
                                }
                            }

                        }

                    }
                    break;
            }
            return null;
        }

        private string GetWizIdFromUrl(string responseUrl)
        {
            int iStart = responseUrl.IndexOf("wizid=", StringComparison.InvariantCultureIgnoreCase) + "wizid=".Length;
            int length = Guid.Empty.ToString().Length;

            return responseUrl.Substring(iStart, length);
        }



        const string regex = "Presenter:\\s+((?<Name>[\\w ]+)\\s*,(?<Title>[\\w ]+\\s*,[\\w ]+)\\s*,?)*";
        static System.Text.RegularExpressions.RegexOptions options = (((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Singleline)
                    | System.Text.RegularExpressions.RegexOptions.ExplicitCapture)
                    | System.Text.RegularExpressions.RegexOptions.Multiline);
        static System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(regex, options);

        #endregion
    }
}
